﻿using Project.Net.Domain.Ex;
using Project.Net.Domain.Log;
using Project.Net.Domain.UserLogin;
using System.Text.Json;

namespace Project.Net.Application.User
{
    public class UserLoginService : IUserLoginService
    {
        private readonly IUserRepository _userRepository;
        private readonly IPasswordHasher _passwordHasher;
        private readonly ITokenGenerator _iTokenGenerator;
        private readonly ILoggerService _loggerService;
        private readonly ITokenValidator _iTokenValidator;
        private readonly IRedisRepository _redisRepository;
        public UserLoginService(IUserRepository userRepository, IPasswordHasher passwordHasher, ITokenGenerator iTokenGenerator, ILoggerService loggerService, ITokenValidator iTokenValidator, IRedisRepository redisRepository)
        {
            _userRepository = userRepository;
            _passwordHasher = passwordHasher;
            _loggerService = loggerService;
            _iTokenValidator = iTokenValidator;
            _iTokenGenerator = iTokenGenerator;
            _redisRepository = redisRepository;
        }
        /// <summary>
        /// 添加用户接口
        /// </summary>
        /// <param name="username"></param>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Domain.UserLogin.User> AddUser(string username, string email, string password)
        {
            try
            {
                // 检查唯一性约束
                if (await _userRepository.ExistsByUsernameAsync(username))
                    throw new DomainException(CodeEnums.其他, "Username already exists");

                if (await _userRepository.ExistsByEmailAsync(email))
                    throw new DomainException(CodeEnums.其他, "Email already registered");

                var userModel = Domain.UserLogin.User.Create(username, email, password, _passwordHasher);
                await _userRepository.AddAsync(userModel);
                return userModel;
            }
            catch (DomainException ex)
            {
                throw new DomainException(ex.Code, ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("用户注册时发生错误", ex);
            }
        }

        public async Task<Domain.UserLogin.User?> GetUserById(int id)
        {
            try
            {
                var key = $"user:{id}";
                var user =await _redisRepository.GetAsync<Domain.UserLogin.User>(key);
                if (user == null)
                {
                    user =await _userRepository.GetUserInfoById(id);
                    //将user转换为json字符串存入redis
                    var jsonStr = JsonSerializer.Serialize(user);
                    await _redisRepository.SetStringAsync(key, jsonStr);
               
                }
                return user;
            }
            catch (DomainException ex)
            {
                throw new DomainException(ex.Code, ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("获取用户信息时发生错误", ex);
            }
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<string> Login(string username, string password)
        {
            var user = await _userRepository.GetByUsernameAsync(username);
            if (user == null)
            {
                throw new DomainException(CodeEnums.其他, "用户不存在");
            }
            var hashedPassword = user.VerifyPassword(password, _passwordHasher);
            if (!hashedPassword)
            {
                throw new DomainException(CodeEnums.其他, "密码错误");
            }
            //生成token
            var token = _iTokenGenerator.GenerateToken(user);
            return token;
        }
    }
}
